#include "utils.h"
#include "terminal.h"
#include "worker.h"

#include <stdio.h>
#include <libgen.h>

/*
#include <jansson.h>

void load_json_config(const char *path) {
    json_t *root;
    json_error_t error;

    root = json_load_file(path, 0, &error);
    if (!root) {
//         handle error
        log_error("[%d] error: on line %d: %s", id, error.line, error.text);
        return;
    }

    if (!json_is_object(root)) {
        log_error("[%d] error: root is not an object", id);
        json_decref(root);
        return;
    }

    json_t *terminal_json, *active_connect_json, *controller_id_json;
    terminal_json = json_object_get(root, "terminal");
    active_connect_json = json_object_get(root, "active_connect");
    controller_id_json = json_object_get(root, "controller_id");

    if (!json_is_array(active_connect_json)) {
        log_error("[%d] error: active_connect is not an array", id);
        json_decref(root);
        return;
    }

    json_t *data, *element;
    data = json_array_get(active_connect_json, id);
    if(!json_is_array(data)) {
        log_error("[%d] error: active_connect is not an array", id);
        json_decref(root);
        return;
    }

    active_connect_len = json_array_size(data);
    for(int j = 0; j < active_connect_len; j++) {
        element = json_array_get(data, j);

//         use the element...
//        printf("active_connect[%d][%d]: %d\n", id, j, json_integer_value(element));
        active_connect[j] = json_integer_value(element);
    }


    if (!json_is_array(terminal_json)) {
        log_error("[%d] error: terminal is not an array", id);
        json_decref(root);
        return;
    }

    for(int i = 0; i < active_connect_len; i++) {
        json_t *data, *id, *ip, *port;
        int idx = active_connect[i];
        data = json_array_get(terminal_json, idx);
        id = json_object_get(data, "id");
        ip = json_object_get(data, "ip");
        port = json_object_get(data, "port");

//         use the id, ip, and port...
//        printf("id: %d\n", json_integer_value(id));
//        printf("ip: %s\n", json_string_value(ip));
//        printf("port: %d\n", json_integer_value(port));

        strcpy(sockets[idx].ip, json_string_value(ip));
        sockets[idx].port = json_integer_value(port);

    }
    {
        json_t *data, *id_json, *ip_json, *port_json;
        int idx = id;
        data = json_array_get(terminal_json, idx);
        id_json = json_object_get(data, "id");
        ip_json = json_object_get(data, "ip");
        port_json = json_object_get(data, "port");

        strcpy(sockets[idx].ip, json_string_value(ip_json));
        sockets[idx].port = json_integer_value(port_json);
    }


    controller_id = json_integer_value(controller_id_json);
//    printf("controller node id: %d\n", json_integer_value(controller_id_json));

// clean up and close
    json_decref(root);

}
*/

void load_txt_config(const char *path) {
    FILE *file = fopen(path, "r");
    if (file == NULL) {
        printf("Unable to open the file: %s.\n", path);
        exit(1);
    }

    char line[BUFSIZ];

    // 读取终端的编号、port和ip
    int t;
    for (int i = 0; i < MAX_TERMINAL_NUM && fgets(line, BUFSIZ, file); i++) {
        sscanf(line, "%d %d %s", &t, &sockets[i].port, sockets[i].ip);
    }

    // 读取每个终端主动连接的其他终端的编号列表
    for (int i = 0; i < MAX_TERMINAL_NUM && fgets(line, BUFSIZ, file); i++) {
        if (i != id) continue;  //不关心的直接跳过
        active_connect_len = 0;
        char* token = strtok(line, " ");
        while (token != NULL && token[0] != '\n') { //特殊处理行末的换行符，否则会多一个0
//            printf("Token: [%s]\n", token);
            active_connect[active_connect_len++] = atoi(token);
            token = strtok(NULL, " ");
        }
    }

    // 读取初始控制终端的编号
    int initial_control;
    if (fgets(line, BUFSIZ, file)) {
        sscanf(line, "%d", &initial_control);
    }

    fclose(file);
}

void test_config() {
    log_trace("[%d] terminal is running on {%s : %d}", id, sockets[id].ip, sockets[id].port);
    for (int i = 0; i < active_connect_len; ++i) {
//        printf("active_connect[%d] : %d\n", i, active_connect[i]);
        log_trace("[%d] active connect terminal %d {%s : %d}", id, active_connect[i], sockets[active_connect[i]].ip, sockets[active_connect[i]].port);
    }
}


int main(int argc, char *argv[]) {
    // 默认日志级别
    int logLevel = LOG_TRACE;

    // 默认配置文件路径
    char *configPath = "../config/test_config.txt";

    // 默认终端数目
    terminalNum = MAX_TERMINAL_NUM;

    // 解析命令行参数
    for (int i = 2; i < argc; i++) {
        if (strcmp(argv[i], "--log-level") == 0 && i + 1 < argc) {
            if (strcmp(argv[i + 1], "TRACE") == 0) {
                logLevel = LOG_TRACE;
            } else if (strcmp(argv[i + 1], "DEBUG") == 0) {
                logLevel = LOG_DEBUG;
            } else if (strcmp(argv[i + 1], "INFO") == 0) {
                logLevel = LOG_INFO;
            } else if (strcmp(argv[i + 1], "WARN") == 0) {
                logLevel = LOG_WARN;
            } else if (strcmp(argv[i + 1], "ERROR") == 0) {
                logLevel = LOG_ERROR;
            } else {
                fprintf(stderr, "Invalid log level: %s\n", argv[i + 1]);
                return 1;
            }
            i++;
        } else if (strcmp(argv[i], "--config") == 0 && i + 1 < argc) {
            // 设置配置文件路径
            configPath = argv[i + 1];
            i++;
        } else if (strcmp(argv[i], "--terminal-num") == 0 && i + 1 < argc) {
            // 设置终端数目
            terminalNum = atoi(argv[i + 1]);
            i++;
        }
    }

//    log_info("run %d terminal", terminalNum);

    // 设置日志级别
    log_set_level(logLevel);
    if (argc < 2) {
        log_fatal("usage: [%s X], X is the index of terminal form 0 - %d", MAX_TERMINAL_NUM, basename(argv[0]));
        exit(1);
    }


    id = atoi(argv[1]);

    load_txt_config(configPath);
    test_config();

    run();


    return 0;
}
